from sqlalchemy import select, delete
from sqlalchemy.ext.asyncio import AsyncSession
from datetime import datetime, date
from typing import Optional, List
import logging

from backend.schemas.schema import StockZTBase
from .models import StockZT, StockDailyKLine, StockMinuteKLine

logger = logging.getLogger(__name__)

async def create_stock_zt(db: AsyncSession, stock_data: dict):
    """
    创建涨停股票数据记录
    
    Args:
        db: 数据库会话
        stock_data: 股票数据字典
        
    Returns:
        StockZT: 创建的股票数据对象
    """
    try:
        # 创建股票对象
        stock = StockZT(
            serial_no=stock_data.get('序号'),
            code=stock_data.get('代码'),
            name=stock_data.get('名称'),
            change_percent=stock_data.get('涨跌幅'),
            latest_price=stock_data.get('最新价'),
            turnover=stock_data.get('成交额'),
            circ_market_value=stock_data.get('流通市值'),
            total_market_value=stock_data.get('总市值'),
            turnover_rate=stock_data.get('换手率'),
            block_fund=stock_data.get('封板资金'),
            first_block_time=stock_data.get('首次封板时间'),
            last_block_time=stock_data.get('最后封板时间'),
            break_block_times=stock_data.get('炸板次数'),
            limit_up_stat=stock_data.get('涨停统计'),
            continuous_limit_up=stock_data.get('连板数'),
            industry=stock_data.get('所属行业'),
            created_at=datetime.now()
        )
        db.add(stock)
        await db.commit()
        await db.refresh(stock)
        logger.info(f"成功创建股票数据记录: {stock.code} - {stock.name}")
        return stock
    except Exception as e:
        await db.rollback()
        logger.error(f"创建股票数据记录时发生错误: {str(e)}")
        raise

async def batch_create_stock_zt(db: AsyncSession, stock_data_list: list):
    """
    批量创建涨停股票数据记录
    
    Args:
        db: 数据库会话
        stock_data_list: 股票数据字典列表
        
    Returns:
        int: 成功创建的记录数
    """
    try:
        response_data = []
        created_count = 0
        for stock_data in stock_data_list:
            stock = StockZT(
                serial_no=stock_data.get('序号'),
                code=stock_data.get('代码'),
                name=stock_data.get('名称'),
                change_percent=stock_data.get('涨跌幅'),
                latest_price=stock_data.get('最新价'),
                turnover=stock_data.get('成交额'),
                circ_market_value=stock_data.get('流通市值'),
                total_market_value=stock_data.get('总市值'),
                turnover_rate=stock_data.get('换手率'),
                block_fund=stock_data.get('封板资金'),
                first_block_time=stock_data.get('首次封板时间'),
                last_block_time=stock_data.get('最后封板时间'),
                break_block_times=stock_data.get('炸板次数'),
                limit_up_stat=stock_data.get('涨停统计'),
                continuous_limit_up=stock_data.get('连板数'),
                industry=stock_data.get('所属行业'),
                created_at=datetime.now()
            )
            db.add(stock)
            created_count += 1
            response_data.append(StockZTBase.model_validate(stock))
        
        await db.commit()
        logger.info(f"成功批量创建 {created_count} 条股票数据记录")
        return response_data
    except Exception as e:
        await db.rollback()
        logger.error(f"批量创建股票数据记录时发生错误: {str(e)}")
        raise

async def get_stock_zt_by_date(db: AsyncSession, query_date: Optional[date] = None):
    """
    根据日期获取涨停股票数据
    
    Args:
        db: 数据库会话
        query_date: 查询日期，如果为None则获取所有数据
        
    Returns:
        list: 股票数据列表
    """
    if query_date:
        result = await db.execute(
            select(StockZT).where(StockZT.created_at >= query_date)
        )
    else:
        # 如果没有指定日期，获取所有数据
        result = await db.execute(select(StockZT))
    return result.scalars().all()

async def get_stock_zt_by_code(db: AsyncSession, code: str):
    """
    根据股票代码获取涨停股票数据
    
    Args:
        db: 数据库会话
        code: 股票代码
        
    Returns:
        list: 股票数据列表
    """
    result = await db.execute(
        select(StockZT).where(StockZT.code == code)
    )
    return result.scalars().all()

async def delete_stock_zt_by_date(db: AsyncSession, query_date: date):
    """
    根据日期删除涨停股票数据
    
    Args:
        db: 数据库会话
        query_date: 查询日期
        
    Returns:
        int: 删除的记录数
    """
    result = await db.execute(
        delete(StockZT).where(StockZT.created_at >= query_date)
    )
    await db.commit()
    deleted_count = result.rowcount
    logger.info(f"成功删除 {deleted_count} 条股票数据记录")
    return deleted_count


async def batch_create_stock_daily_kline(db: AsyncSession, code: str, kline_data_list: List[dict]):
    """
    批量创建股票日K线数据记录
    
    Args:
        db: 数据库会话
        code: 股票代码
        kline_data_list: K线数据字典列表
        
    Returns:
        int: 成功创建的记录数
    """
    try:
        created_count = 0
        for kline_data in kline_data_list:
            kline = StockDailyKLine(
                code=code,
                date=kline_data.get('日期'),
                open=kline_data.get('开盘'),
                high=kline_data.get('最高'),
                low=kline_data.get('最低'),
                close=kline_data.get('收盘'),
                volume=kline_data.get('成交量'),
                turnover=kline_data.get('成交额'),
                amplitude=kline_data.get('振幅'),
                change_percent=kline_data.get('涨跌幅'),
                created_at=datetime.now()
            )
            db.add(kline)
            created_count += 1
        
        await db.commit()
        logger.info(f"成功批量创建 {created_count} 条日K线数据记录")
        return created_count
    except Exception as e:
        await db.rollback()
        logger.error(f"批量创建日K线数据记录时发生错误: {str(e)}")
        raise


async def batch_create_stock_minute_kline(db: AsyncSession, code: str, kline_data_list: List[dict]):
    """
    批量创建股票分钟K线数据记录
    
    Args:
        db: 数据库会话
        code: 股票代码
        kline_data_list: K线数据字典列表
        
    Returns:
        int: 成功创建的记录数
    """
    try:
        created_count = 0
        for kline_data in kline_data_list:
            kline = StockMinuteKLine(
                code=code,
                datetime=kline_data.get('时间'),
                open=kline_data.get('开盘'),
                high=kline_data.get('最高'),
                low=kline_data.get('最低'),
                close=kline_data.get('收盘'),
                volume=kline_data.get('成交量'),
                turnover=kline_data.get('成交额'),
                created_at=datetime.now()
            )
            db.add(kline)
            created_count += 1
        
        await db.commit()
        logger.info(f"成功批量创建 {created_count} 条分钟K线数据记录")
        return created_count
    except Exception as e:
        await db.rollback()
        logger.error(f"批量创建分钟K线数据记录时发生错误: {str(e)}")
        raise